﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Net.NetworkInformation;
using System.Windows.Controls;

namespace Dota2NetworkTester
{
    public partial class Form1 : Form
    {
        List<Server> servers = new List<Server>();
        public string name = "";
        public string ip = "";
        public string region;
        public int howManyPings;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //RefreshPing();
            LoadServerList();
            foreach(Server sv in servers){
                cb_serverList.Items.Add(sv.Name);
            }
            cb_serverList.SelectedIndex = 0;

            
            //set invisible net connection labels
            lbl_generalPing.Visible = false;
            lbl_maxNetSpike.Visible = false;
            lbl_netStatus.Visible = false;
            lbl_visualGeneralPing.Visible = false;
            lbl_visualMaxNetSpike.Visible = false;
            lbl_visualPackageLoss.Visible = false;
            lbl_PackageLoss.Visible = false;
            ch_GraphPing.Visible = false;
            tabControl1.Visible = false;
        }

        private void LoadServerList()
        {
            XDocument xmlDoc = XDocument.Parse(Dota2NetworkTester.Properties.Resources.servers);
            List<Server> listServers = (from _server in xmlDoc.Element("Servers").Elements("Server")
                                        select new Server
                                        {
                                            Name = _server.Element("Name").Value,
                                            IP = _server.Element("Ip").Value,
                                            Region = _server.Element("Region").Value
                                        }).ToList();
            foreach (var _server in listServers)
            {
                servers.Add(_server);
            }
        }

        private void lbl_statusSA_Click(object sender, EventArgs e)
        {

        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            RefreshPing();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            RefreshPing();
        }

        public void RefreshPing()
        {
            ip = servers[cb_serverList.SelectedIndex].IP;
            name = servers[cb_serverList.SelectedIndex].Name;
            long ping = new Ping().Send(ip).RoundtripTime;
            lbl_ping.Text = ping + "ms";

            if (ping >= 200)
            {
                lbl_ping.ForeColor = Color.Red;
                lbl_status.ForeColor = Color.Red;
                lbl_status.Text = "Not Playable";
            }
            else
            {
                lbl_ping.ForeColor = Color.Green;
                lbl_status.ForeColor = Color.Green;
                lbl_status.Text = "Playable";
            }

            region = servers[cb_serverList.SelectedIndex].Region;

            if (region == "Brazil")
            {
                System.Drawing.Image flag = (System.Drawing.Image)Dota2NetworkTester.Properties.Resources.flag_brazil;
                pb_flag.Image = flag;
            }
            if (region == "Chile")
            {
                System.Drawing.Image flag = (System.Drawing.Image)Dota2NetworkTester.Properties.Resources.flag_chile;
                pb_flag.Image = flag;
            }
            if (region == "Peru")
            {
                System.Drawing.Image flag = (System.Drawing.Image)Dota2NetworkTester.Properties.Resources.flag_peru;
                pb_flag.Image = flag;
            }
            if (region == "North America")
            {
                System.Drawing.Image flag = (System.Drawing.Image)Dota2NetworkTester.Properties.Resources.flag_usa;
                pb_flag.Image = flag;
            }
            if (region == "Europe")
            {
                System.Drawing.Image flag = (System.Drawing.Image)Dota2NetworkTester.Properties.Resources.europe;
                pb_flag.Image = flag;
            }
            if (region == "Asia")
            {
                System.Drawing.Image flag = (System.Drawing.Image)Dota2NetworkTester.Properties.Resources.singapore;
                pb_flag.Image = flag;
            }
        }

        private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://steamcommunity.com/id/totiigamer");
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            MakeConnectionTest();
        }

        public void MakeConnectionTest()        {
            //set visible net connection labels
            lbl_generalPing.Visible = true;
            lbl_maxNetSpike.Visible = true;
            lbl_netStatus.Visible = true;
            lbl_visualGeneralPing.Visible = true;
            lbl_visualMaxNetSpike.Visible = true;
            lbl_visualPackageLoss.Visible = true;
            lbl_PackageLoss.Visible = true;
            ch_GraphPing.Visible = true;
            tabControl1.Visible = true;
            //create list that will store the 0 pings packages
            //0 ping package = package lost
            List<long> lostPackages = new List<long>();
            //clean the list to get always no pings
            lostPackages.Clear();

            long actualPing;
            long generalLatency = 0;
            List<long> latencias = new List<long>();

            for (int i = 0; i < 100; i++)
            {
                actualPing = new Ping().Send(ip).RoundtripTime;
                latencias.Add(actualPing);
            }
            foreach (var series in ch_GraphPing.Series)
            {
                series.Points.Clear();
            }
            foreach (long _ping in latencias)
            {
                double db = 0;
                generalLatency += _ping;
                if (_ping == 0)
                {
                    lostPackages.Add(_ping);
                }
                ch_GraphPing.Series["Ping"].Points.AddXY(db++, (double)_ping);
                richTextBox1.Text += "Respuesta obtenido: " + _ping + "ms \n";
            }
            generalLatency = generalLatency / latencias.Count;

            lbl_generalPing.Text = generalLatency.ToString() + "ms";
            lbl_maxNetSpike.Text = latencias.Max().ToString() + "ms";

            if (generalLatency <= 250 && latencias.Max() <= 1000)
            {
                lbl_generalPing.ForeColor = Color.Green;
                lbl_netStatus.Text = "Good connection Status in " + name;
                lbl_netStatus.ForeColor = Color.Green;
            }
            else
            {
                lbl_generalPing.ForeColor = Color.Red;
                lbl_netStatus.Text = "Bad connection Status in " + name;
                lbl_netStatus.ForeColor = Color.Red;
            }
            if (lostPackages.Count < 5 && lostPackages.Count > 1)
            {
                lbl_PackageLoss.ForeColor = Color.Orange;
            }
            else if (lostPackages.Count > 5)
            {
                lbl_PackageLoss.ForeColor = Color.Red;
            }
            else if (lostPackages.Count < 1)
            {
                lbl_PackageLoss.ForeColor = Color.Green;
            }
            lbl_PackageLoss.Text = (lostPackages.Count * latencias.Count / 100).ToString() + "%";

            MessageBox.Show("Test finished!");
        }
    }

    
}
